#include <GL/glut.h>
#include <stdlib.h>
#include "sphere.h"
#include "loadtga.h"

#define MUNDO 4.0f

int xRot, yRot, zRot;
GLuint texturaMapa;

void inicializar (void);
void redimensiona (int alto, int ancho);
void dibuja (void);
void teclado (unsigned char key, int cx, int cy);
void tecladoEspecial (int key, int cy, int cx);

int main(int argc, char** argv) {
   
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize (640, 480);
   glutInitWindowPosition (100, 105);
   glutCreateWindow (argv[0]);
   inicializar();
   
   glutDisplayFunc(dibuja);
   glutReshapeFunc(redimensiona);
   glutKeyboardFunc(teclado);
   glutSpecialFunc(tecladoEspecial);

   glutMainLoop();
   
   return 0;
}

void inicializar () {
   glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
   
   glEnable(GL_DEPTH_TEST);
   
   //Materiales e iluminación
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   
   //Hacemos culling en la parte de atras
   glEnable(GL_CULL_FACE);
   glCullFace(GL_BACK);

   //Prendemos el modo de texturas
   glEnable(GL_TEXTURE_2D);
   //Esta es la interpolacion hiperbolica
   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
   //Cargamos la textura a memoria
   GLbyte *pBytes;
   GLint nWidth, nHeight, nComponents;
   GLenum format;

   glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_DECAL);
   glGenTextures(1, &texturaMapa);
   //Cargamos la textura en memoria
   pBytes = gltLoadTGA("world32k.tga", &nWidth, &nHeight, &nComponents, &format);
   glBindTexture(GL_TEXTURE_2D, texturaMapa);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0, format, GL_UNSIGNED_BYTE, pBytes);
   free(pBytes);

   //Las rotaciones de la camara
   zRot = 0.0;
   xRot = 270;
   yRot = 180;

}

void redimensiona (int ancho, int alto) {
   float aspect;
   
   glViewport (0, 0, ancho, alto);
   glMatrixMode (GL_PROJECTION);
   glLoadIdentity ();
   
   if (alto == 0){
   	  alto = 1;
   }
   
   aspect = (float) ancho / (float) alto;
   
   if (ancho <= alto) {
   	  glOrtho(-MUNDO, MUNDO, -MUNDO/aspect, MUNDO/aspect, -MUNDO, MUNDO);
   	  
   } else {
   	  glOrtho(-MUNDO * aspect, MUNDO * aspect, -MUNDO, MUNDO, -MUNDO, MUNDO);
   }
   
   /*
      gluPerspective(60, aspect, 0.1, 2*MUNDO);
   */
   
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

void teclado (unsigned char key, int cx, int cy) {
	
	switch (key) {
		case 27:
		   exit(0);
		break;
		
		default: break;
	}
	
	glutPostRedisplay();
}

void tecladoEspecial (int key, int cy, int cx) {
	
	switch (key) {
		case GLUT_KEY_UP:
			xRot += 10;
		break;
		
		case GLUT_KEY_DOWN:
			xRot -= 10;
		break;
		
		case GLUT_KEY_LEFT:
			yRot -= 10;
		break;
		
		case GLUT_KEY_RIGHT:
			yRot += 10;
		break;
		
		case GLUT_KEY_PAGE_UP:
			zRot += 10;
		break;
		
		case GLUT_KEY_PAGE_DOWN:
			zRot -= 10;
		break;
		
		
		default: break;
	}
	
	glutPostRedisplay();
}


void dibuja (void) {
	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	glPushMatrix();
		//Transformasión de vision
		glRotatef((float)zRot, 0.0, 0.0, 1.0);
		glRotatef((float)yRot, 0.0, 1.0, 0.0);
		glRotatef((float)xRot, 1.0, 0.0, 0.0);
		
		glBindTexture(GL_TEXTURE_2D, texturaMapa);
		drawTexturedSphere(3.0, 50, 50);
	glPopMatrix();    
	
	glutSwapBuffers();
}
